home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / archivers / xpk / xpk_source / xpkmaster / open.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  15KB  |  477 lines

  1. #ifndef XPKMASTER_OPEN_C
  2. #define XPKMASTER_OPEN_C
  3.  
  4. /* Routinesheader
  5.  
  6.     Name:        open.c
  7.     Main:        xpkmaster
  8.     Versionstring:    $VER: open.c 1.19 (30.10.1998)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Opening and initialisation routines for XPK files
  12.  
  13.  1.0   06.10.96 : first real version
  14.  1.1   28.10.96 : reincluded A4 support
  15.  1.2   03.03.97 : added Prefs, corrected length recognition
  16.  1.3   07.03.97 : fixed prefs handling, new features
  17.  1.4   09.03.97 : added DEBUG statement
  18.  1.5   28.03.97 : auto decrunch password
  19.  1.6   29.03.97 : fixed prefs stuff, moved getinlen into hooks
  20.  1.7   31.03.97 : changed the password stuff
  21.  1.8   19.12.97 : added xfdmaster.library support
  22.  1.9   22.12.97 : fixed auto password problem
  23.  1.10  27.12.97 : fixed GetPassword error
  24.  1.11  09.01.98 : better key handling
  25.  1.12  21.01.98 : added password verification for packing
  26.  1.13  24.01.98 : fixed xfdmaster support a bit
  27.  1.14  17.02.98 : fixe long file problem added in last version
  28.  1.15  21.02.98 : uses new style register definition
  29.  1.16  26.03.98 : some optimizations
  30.  1.17  26.08.98 : may skip reading insize for packing, when no inhook
  31.  1.18  13.09.98 : removed PP stuff
  32.  1.19  30.10.98 : some changes for seek support
  33. */
  34.  
  35. #include <xpk/xpkprefs.h>
  36. #include <exec/memory.h>
  37. #include <proto/exec.h>
  38. #include <proto/dos.h>
  39. #include <proto/xpkmaster.h>
  40. #include <proto/xpksub.h>
  41. #include <proto/xfdmaster.h>
  42. #include "xpkmaster.h"
  43. #include "texts.h"
  44.  
  45. static const struct XpkInfo DONTInfo = { 1,0,0,1,"DONT","Copy",
  46. 0, 0x55534552, XPKIF_PK_CHUNK|XPKIF_UP_CHUNK, DEFAULTCHUNKSIZE, 1,
  47. DEFAULTCHUNKSIZE,0,0,0,0,100,0,0,0,0,0,0,0,0};
  48. /* XpkMode is not initialized! Should not be used anywhere */
  49.  
  50. static LONG xpkopenwrite(struct XpkBuffer **, struct TagItem *);
  51. static LONG GetPrefsPacker(struct XpkBuffer *);
  52. static LONG GetPassword(struct XpkBuffer *, struct TagItem *, ULONG);
  53. static struct XpkTypeData *BufRecog(ULONG, struct XpkBuffer *,
  54.   struct XpkPrefsSemaphore *);
  55.  
  56. XPK_ALLINONE ASM(LONG) xpkopen(REG(a0, struct XpkBuffer **xbufp),
  57. REG(a1, struct TagItem *tags), REG(d2, ULONG examine A4PROTO))
  58. {
  59.   struct XpkBuffer     *xbuf;
  60.   struct XpkStreamHeader *globhdr;
  61.   struct XpkFib         *fib;
  62.  
  63. #if defined(DEBUG) && defined(SUPPORT_A4)
  64.   DebugRunTime("xpkopen: A4 = %ld", a4);
  65. #elif defined (DEBUG)
  66.   DebugRunTime("xpkopen");
  67. #endif
  68.  
  69.   if(!(*xbufp = xbuf = initxbuf()))
  70.     return parseerrortags(tags, XPKERR_NOMEM);
  71.  
  72. #ifdef SUPPORT_A4
  73.   xbuf->xb_regA4 = a4;
  74. #endif
  75.  
  76.   globhdr = &xbuf->xb_Headers.h_Glob;
  77.   fib = &xbuf->xb_Fib;
  78.  
  79.   if(parsebuftags(xbuf, tags))
  80.     goto Abort;
  81.  
  82.   if(xbuf->xb_Flags & XMF_PACKING) /* Call pack open function */
  83.     return xpkopenwrite(xbufp, tags);
  84.  
  85.   if(!hookread(xbuf, XIO_READ, globhdr, 4)) /* Read first longword */
  86.   {
  87.     if(xbuf->xb_Result != XPKERR_TRUNCATED)
  88.       goto Abort;
  89.     /* else handle now as uncompressed file */
  90.   }
  91.  
  92.   /***************************** Standard XPK file **********************/
  93.   if(globhdr->xsh_Pack == XPK_COOKIE)
  94.   {
  95.     UWORD exthlen = 0;        /* size of extended header if present */
  96.     struct Library * XpkSubBase;
  97.  
  98.     xbuf->xb_Format = XPKMODE_UPSTD;
  99.  
  100.     /* Read rest of the global header */
  101.     if(!hookread(xbuf, XIO_READ, (STRPTR) globhdr + 4, sizeof(struct XpkStreamHeader) - 4))
  102.       goto Abort;
  103.  
  104.     if(hchecksum((STRPTR) globhdr, sizeof(struct XpkStreamHeader)))
  105.     {
  106.       xbuf->xb_Result = XPKERR_CHECKSUM;
  107.       goto Abort;
  108.     }
  109.  
  110.     if(globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS)
  111.       xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrLong);
  112.     else
  113.       xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrWord);
  114.  
  115.     if(globhdr->xsh_Flags & XPKSTREAMF_EXTHEADER)
  116.     {
  117.       if(!hookread(xbuf, XIO_READ, &exthlen, sizeof(UWORD)))
  118.     goto Abort;
  119.       if(!hookread(xbuf, XIO_READ, NULL, exthlen))
  120.     goto Abort;
  121.       exthlen += sizeof(UWORD);    /* for unwinding while XpkExamine */
  122.     }
  123.  
  124.     if(!hookread(xbuf, XIO_READ, &xbuf->xb_Headers.h_Loc,
  125.     xbuf->xb_Headers.h_LocSize))  /* first lochdr */
  126.       goto Abort;
  127.  
  128.     fib->xf_CCur = sizeof(struct XpkStreamHeader);
  129.     if(updatefib(xbuf))
  130.       goto Abort;
  131.     xbuf->xb_InLen = fib->xf_CLen;
  132.  
  133.     if(!(XpkSubBase = opensub(xbuf, globhdr->xsh_Type)))
  134.       goto Abort;
  135.  
  136.     if(globhdr->xsh_SubVrs > xbuf->xb_SubInfo->xi_LibVersion)
  137.     {
  138.       xbuf->xb_Result = XPKERR_OLDSUBLIB;
  139.       goto Abort;
  140.     }
  141.  
  142.     xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_UnpackMsg ?
  143.       xbuf->xb_SubInfo->xi_UnpackMsg : strings[TXT_UNPACKING_UPPER];
  144.     xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
  145.     xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_UnpackedMsg ?
  146.       xbuf->xb_SubInfo->xi_UnpackedMsg : strings[TXT_UNPACKED];
  147.  
  148.     if(globhdr->xsh_Flags & XPKSTREAMF_PASSWORD)
  149.       fib->xf_Flags |= XPKFLAGS_PASSWORD;
  150.  
  151.     if(examine && !hookread(xbuf, XIO_SEEK, 0,
  152.     -(sizeof(struct XpkStreamHeader) + xbuf->xb_Headers.h_LocSize+exthlen)))
  153.       goto Abort;
  154.  
  155.     goto Exit;
  156.   }
  157.  
  158.   if(!hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_RMsg.xmm_Size))
  159.     goto Abort; /* redo last read bytes */
  160.  
  161.   if(xbuf->xb_InLen == 0xFFFFFFFF)
  162.   {
  163.     if(!hookread(xbuf, XIO_TOTSIZE, 0, 0))    /* get input length */
  164.       goto Abort;
  165.     else if(xbuf->xb_RMsg.xmm_Size)
  166.       xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
  167.   }
  168.  
  169.   fib->xf_CLen = xbuf->xb_InLen;
  170.  
  171.   /**************************** xfdmaster file **************************/
  172.   if(xbuf->xb_Flags & XMF_XFD &&
  173.   (xbuf->xb_SubBase = OpenLibrary("xfdmaster.library", 38)))
  174.   {
  175.     struct xfdMasterBase *xfdMasterBase = (struct xfdMasterBase *) xbuf->xb_SubBase;
  176.     struct xfdBufferInfo *xbi;
  177.  
  178.     if(!(xbi = xbuf->xb_xfd = (struct xfdBufferInfo *) xfdAllocObject(XFDOBJ_BUFFERINFO)))
  179.       goto Abort;
  180.     if(!(xbi->xfdbi_SourceBuffer = hookread(xbuf, XIO_READ, 0, xbuf->xb_InLen)))
  181.       goto Abort;
  182.     xbi->xfdbi_SourceBufLen = xbuf->xb_InLen;
  183.     xbi->xfdbi_Flags = XFDFF_RECOGEXTERN|XFDFF_RECOGTARGETLEN|XFDFF_RECOGUSERTARGET;
  184.  
  185.     if(xfdRecogBuffer(xbi) && (xbi->xfdbi_PackerFlags & XFDPFF_DATA) &&
  186.     (LONG) xbi->xfdbi_FinalTargetLen != -1)
  187.     {
  188.       xbuf->xb_Format = XPKMODE_UPXFD;
  189.       if(xbi->xfdbi_PackerFlags & XFDPFF_PASSWORD)
  190.         xbuf->xb_Fib.xf_Flags |= XPKFLAGS_PASSWORD;
  191.       if(xbi->xfdbi_PackerFlags & XFDPFF_KEY16)
  192.         xbuf->xb_Fib.xf_Flags |= XPKFLAGS_KEY16;
  193.       if(xbi->xfdbi_PackerFlags & XFDPFF_KEY32)
  194.         xbuf->xb_Fib.xf_Flags |= XPKFLAGS_KEY32;
  195.       fib->xf_Type = XPKTYPE_PACKED;
  196.       fib->xf_ULen = xbi->xfdbi_FinalTargetLen;
  197.       fib->xf_NLen = xbi->xfdbi_MinTargetLen;
  198.       fib->xf_ID = XFD_COOKIE;
  199.       percentages(fib);
  200.       xbuf->xb_Prog.xp_Activity = strings[TXT_UNPACKING_UPPER];
  201.       xbuf->xb_Prog.xp_PackerName = "XFDMaster";
  202.       xbuf->xb_LastMsg = strings[TXT_UNPACKED];
  203.  
  204.       if(examine && !hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_InLen))
  205.         goto Abort; /* return to start */
  206.  
  207. #ifdef DEBUG
  208.       DebugRunTime("xpkopen: XFD, InLen %ld, OutLen %ld, NLen %ld",
  209.       xbuf->xb_InLen, fib->xf_ULen, fib->xf_NLen);
  210. #endif
  211.       goto Exit;
  212.     } /* xfdRecogBuffer */
  213.  
  214.     if(!hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_InLen))
  215.       goto Abort; /* return to start */
  216.   }
  217.  
  218.   /*************************** Uncompressed file ************************/
  219.   if(examine || xbuf->xb_Flags & XMF_PASSTHRU)        /* Unpacked */
  220.   {
  221.     xbuf->xb_Format = XPKMODE_UPUP;
  222.  
  223.     fib->xf_Type = XPKTYPE_UNPACKED;
  224.     fib->xf_ULen = xbuf->xb_InLen;
  225.     fib->xf_NLen = Min(DEFAULTCHUNKSIZE, xbuf->xb_InLen) + XPK_MARGIN;
  226.     fib->xf_ID = ROW_OF_MINUS;
  227.  
  228.     xbuf->xb_Prog.xp_Activity = strings[TXT_READING];
  229.     xbuf->xb_Prog.xp_PackerName = "Master";
  230.     xbuf->xb_LastMsg = strings[TXT_READ];
  231.  
  232.     xbuf->xb_Result = XPKERR_OK;  /* if != 0 it was XPKERR_TRUNCATED */
  233.  
  234.     goto Exit;
  235.   }
  236.  
  237.   xbuf->xb_Result = XPKERR_NOTPACKED;    /* Can't unpack, can't passthru */
  238.  
  239. Abort:
  240.   *xbufp = 0;
  241.   return XpkClose((struct XpkFib *) xbuf);
  242.  
  243. Exit:
  244.   if(!examine && (
  245.   ((fib->xf_Flags & XPKFLAGS_PASSWORD) && !xbuf->xb_Password) ||
  246.   ((fib->xf_Flags & XPKFLAGS_KEY16) && !(xbuf->xb_Flags & XMF_KEY16)) ||
  247.   ((fib->xf_Flags & XPKFLAGS_KEY32) && !(xbuf->xb_Flags & XMF_KEY32)))
  248.   && (xbuf->xb_Result = GetPassword(xbuf, tags, FALSE)))
  249.       goto Abort;
  250.  
  251.   return XPKERR_OK;
  252. }
  253.  
  254. /***************************** Open for packing *************************/
  255. static LONG xpkopenwrite(struct XpkBuffer **xbufp, struct TagItem *tags)
  256. {
  257.   struct XpkBuffer        *xbuf        = *xbufp;
  258.   struct XpkStreamHeader    *globhdr    = &xbuf->xb_Headers.h_Glob;
  259.   struct Library        *XpkSubBase;
  260.   LONG                 res;
  261.  
  262.   xbuf->xb_Format = XPKMODE_PKSTD;
  263.  
  264.   if(xbuf->xb_InLen == 0xFFFFFFFF && xbuf->xb_RHook)
  265.   {
  266.     if(!hookread(xbuf, XIO_TOTSIZE, 0, 0))    /* get input length */
  267.       return xbuf->xb_Result;
  268.     else if(xbuf->xb_RMsg.xmm_Size)
  269.       xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
  270.   }
  271.  
  272.   xbuf->xb_Fib.xf_ULen = xbuf->xb_InLen;
  273.  
  274.   if(!(XpkSubBase = xbuf->xb_SubBase) &&  /* Do we know the sublib? */
  275.   (xbuf->xb_Result = GetPrefsPacker(xbuf)))
  276.     goto Abort; /* no sublib and no prefs packer finder */
  277.  
  278.   if(xbuf->xb_Password && !(xbuf->xb_SubInfo->xi_Flags & XPKIF_ENCRYPTION))
  279.   {
  280.     xbuf->xb_Result = XPKERR_NOCRYPT;
  281.     goto Abort;
  282.   }
  283.  
  284.   if(!xbuf->xb_Password && (xbuf->xb_SubInfo->xi_Flags & XPKIF_NEEDPASSWD))
  285.   { /* automatic password requester */
  286.     if((xbuf->xb_Result = GetPassword(xbuf, tags, TRUE)))
  287.       goto Abort;
  288.   }
  289.  
  290.   if(!(xbuf->xb_Flags & XMF_LOSSYOK) &&
  291.   xbuf->xb_SubInfo->xi_Flags & XPKIF_LOSSY)
  292.   {
  293.     xbuf->xb_Result = XPKERR_LOSSY;
  294.     goto Abort;
  295.   }
  296.  
  297.   if(xbuf->xb_PackingMode > 100)    /* Is packing mode valid? */
  298.     xbuf->xb_PackingMode = 100;        /* Use max */
  299.  
  300.   if(xbuf->xb_InLen != 0xFFFFFFFF)
  301.   {
  302.     if(!hookwrite(xbuf, XIO_TOTSIZE, 0, ROUNDLONG
  303.     (xbuf->xb_InLen + (xbuf->xb_InLen >> 5)) + (XPK_MARGIN<<1)))
  304.       goto Abort;
  305.   }
  306.  
  307.   /************************* Find the chunk size ************************/
  308.   if((xbuf->xb_ChunkSize == 0) &&
  309.   ((xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_DefPkInChunk) == 0))
  310.     xbuf->xb_ChunkSize = DEFAULTCHUNKSIZE;
  311.   if(xbuf->xb_ChunkSize < xbuf->xb_SubInfo->xi_MinPkInChunk)
  312.     xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MinPkInChunk;
  313.   if((xbuf->xb_SubInfo->xi_MaxPkInChunk) &&
  314.   (xbuf->xb_ChunkSize > xbuf->xb_SubInfo->xi_MaxPkInChunk))
  315.     xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MaxPkInChunk;
  316.  
  317.   /************************ Prepare global header ***********************/
  318.   globhdr->xsh_Pack = 0;        /* Initialize the global header */
  319.   globhdr->xsh_Type = xbuf->xb_SubID;
  320.  
  321.   if(xbuf->xb_ChunkSize > 65000) /* (0xFFFF-XPK_MARGIN) and some bytes security */
  322.     globhdr->xsh_Flags |= XPKSTREAMF_LONGHEADERS;
  323.   if(xbuf->xb_Password)
  324.     globhdr->xsh_Flags |= XPKSTREAMF_PASSWORD;
  325.  
  326.   xbuf->xb_Headers.h_LocSize = globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS
  327.     ? sizeof (struct XpkChunkHdrLong)
  328.     : sizeof (struct XpkChunkHdrWord);
  329.  
  330.   memset(globhdr->xsh_Initial, 0xff, 16);    /* Read first 16 bytes */
  331.  
  332.   xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_PackMsg ?
  333.   xbuf->xb_SubInfo->xi_PackMsg : strings[TXT_PACKING_UPPER];
  334.   xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
  335.   xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_PackedMsg ?
  336.   xbuf->xb_SubInfo->xi_PackedMsg : strings[TXT_PACKED];
  337.  
  338. Abort:
  339.   xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur,
  340.   xbuf->xb_ChunkSize);
  341.  
  342.   if((res = xbuf->xb_Result))
  343.     res = XpkClose((struct XpkFib *) xbuf);
  344.  
  345.   return res;
  346. }
  347.  
  348. typedef ASM(struct XpkTypeData *) (*RecogFunc) (REG(a0, STRPTR),
  349.     REG(a1, STRPTR), REG(d0, ULONG), REG(d1, ULONG),
  350.     REG(a2, struct TagItem *));
  351.  
  352. static LONG GetPrefsPacker(struct XpkBuffer *xbuf)
  353. {
  354.   LONG ret = XPKERR_UNKNOWN;
  355.   struct XpkPrefsSemaphore *sem;
  356.   ULONG bufsize;
  357.   struct XpkTypeData *td = 0;
  358.  
  359.   if((xbuf->xb_Flags & XMF_NOPREFS) || !xbuf->xb_RHook)
  360.     return XPKERR_BADPARAMS;
  361.   if(!(sem = GetPrefsSem()))
  362.     return XPKERR_NOFUNC;
  363.  
  364.   bufsize = Min(xbuf->xb_InLen, sem->xps_RecogSize);
  365.  
  366.   if(sem->xps_RecogFunc && (td = BufRecog(bufsize, xbuf, sem)) ==
  367.   (struct XpkTypeData *) 0xFFFFFFFF)
  368.     td = BufRecog(xbuf->xb_InLen, xbuf, sem);
  369.  
  370.   if(!td || td == (struct XpkTypeData *) 0xFFFFFFFF)
  371.     td = sem->xps_MainPrefs ? sem->xps_MainPrefs->xmp_DefaultType : 0;
  372.  
  373.   if(td)
  374.   {
  375.     if(td->xtd_Flags & XTD_NoPack)
  376.     {
  377.       xbuf->xb_Flags |= XMF_NOPACK;
  378.       xbuf->xb_SubInfo = (struct XpkInfo *) &DONTInfo;
  379.       ret = XPKERR_OK;
  380.     }
  381.     else if(!(td->xtd_Flags & XTD_ReturnError))
  382.     {
  383.       struct Library *XpkSubBase;
  384.       struct XpkInfo *subinfo;
  385.  
  386.       if((XpkSubBase = opensub(xbuf, td->xtd_StdID)))
  387.       {
  388.     ret = XPKERR_OK;
  389.         subinfo = XpksPackerInfo();
  390.  
  391.         xbuf->xb_ChunkSize = td->xtd_ChunkSize;
  392.         xbuf->xb_PackingMode = ( td->xtd_Mode ? td->xtd_Mode :
  393.           subinfo->xi_DefMode);
  394. //    if(!(xbuf->xb_Password) && td->xtd_Password && 
  395. //    (xbuf->xb_PasswordSize = strlen(td->xtd_Password)))
  396. //    {
  397. //      /* we need a buffer including end byte! --> ++size */
  398. //      if(!(xbuf->xb_Password = (STRPTR)
  399. //      AllocMem(++xbuf->xb_PasswordSize, MEMF_PUBLIC)))
  400. //        ret = XPKERR_NOMEM;
  401. //        else
  402. //      {
  403. //        xbuf->Flags |= XMF_OWNPASSWORD;
  404. //        CopyMem(td->xtd_Password, xbuf->xb_Password, xbuf->xb_PasswordSize);
  405. //      }
  406. //    }
  407.       }
  408.     }
  409.     else
  410.       ret = XPKERR_NOMETHOD;
  411.   }
  412.  
  413.   if(td->xtd_Memory && td->xtd_MemorySize)
  414.     FreeMem(td->xtd_Memory, td->xtd_MemorySize);
  415.  
  416.   ReleaseSemaphore((struct SignalSemaphore *) sem);
  417.   return ret;
  418. }
  419.  
  420. static LONG GetPassword(struct XpkBuffer *xbuf, struct TagItem *tags,
  421. ULONG verify)
  422. {
  423.  if(xbuf->xb_Flags & XMF_AUTOPASSWD)
  424.  {
  425.    if(xbuf->xb_Fib.xf_Flags & XPKFLAGS_KEY32)
  426.    {
  427.      xbuf->xb_Result = XpkPassRequestTags(XPK_Key32BitPtr,
  428.      &xbuf->xb_PassKey32, TAG_MORE, tags, TAG_DONE);
  429.      xbuf->xb_Flags |= XMF_KEY32;
  430.    }
  431.    else if(xbuf->xb_Fib.xf_Flags & XPKFLAGS_KEY16)
  432.    {
  433.      xbuf->xb_Result = XpkPassRequestTags(XPK_Key16BitPtr,
  434.      &xbuf->xb_PassKey16, TAG_MORE, tags, TAG_DONE);
  435.      xbuf->xb_Flags |= XMF_KEY16;
  436.    }
  437.    else
  438.    {
  439.      if(!(xbuf->xb_Password = (STRPTR) AllocMem(AUTO_PASS_SIZE, MEMF_PUBLIC)))
  440.        return XPKERR_NOMEM;
  441.      xbuf->xb_PasswordSize = AUTO_PASS_SIZE;
  442.      xbuf->xb_Flags |= XMF_OWNPASSWORD; /* must be freed later */
  443.  
  444.      xbuf->xb_Result = XpkPassRequestTags(XPK_PasswordBuf,
  445.      xbuf->xb_Password, XPK_PassBufSize, xbuf->xb_PasswordSize,
  446.      XPK_PassVerify, verify, TAG_MORE, tags, TAG_DONE);
  447.    }
  448.  
  449.    return xbuf->xb_Result;
  450.  }
  451.  return XPKERR_NEEDPASSWD;
  452. }
  453.  
  454. static struct XpkTypeData *BufRecog(ULONG bufsize, struct XpkBuffer *xbuf,
  455. struct XpkPrefsSemaphore *sem)
  456. {
  457.   STRPTR bufptr;
  458.   struct XpkTypeData *ret = 0;
  459.   struct TagItem tag[] = {
  460.   { XPK_FileName, 0},
  461.   { XPK_PackMode, 0},
  462.   { TAG_DONE, 0}};
  463.  
  464.   tag[0].ti_Data = (ULONG) xbuf->xb_Prog.xp_FileName;
  465.   tag[1].ti_Data = xbuf->xb_PackingMode;
  466.  
  467.   if((bufptr = (STRPTR) hookread(xbuf, XIO_READ, 0, bufsize)))
  468.   {
  469.     ret = (((RecogFunc) sem->xps_RecogFunc) (bufptr,
  470.     xbuf->xb_RMsg.xmm_FileName, bufsize, xbuf->xb_InLen, tag));
  471.     hookread(xbuf, XIO_SEEK, 0, -bufsize);
  472.   }
  473.   return ret;
  474. }
  475.  
  476. #endif /* XPKMASTER_OPEN_C */
  477.